﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SQLite;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace AZMapDBHelperPlugin
{
    public static class AZDBSQLiteHelper
    {
        private const string ALTER_TEMP_TABLE_NAME_TO_TILES = "ALTER TABLE temp RENAME TO tiles";
        private const string CONN_STRING = "Data Source=\"{0}\";FailIfMissing=False;Page Size=32768;Pooling=True";
        private const string COPY_TILES_INTO_SQLITEDB = "INSERT INTO temp SELECT X AS x,Y AS y,Zoom AS z,Data AS image FROM tiles ";
        private const string CREATE_BUNDLES_TABLE_SQL = "CREATE Table Bundles(Zoom int,BundleIndex int64,Bundle BLOB,primary key(Zoom,BundleIndex) );";
        private const string CREATE_CONTENTS_TABLE_SQL = "CREATE TABLE gpkg_contents (table_name TEXT NOT NULL PRIMARY KEY,data_type TEXT NOT NULL,identifier TEXT UNIQUE,description TEXT DEFAULT '',last_change DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),min_x DOUBLE,min_y DOUBLE,max_x DOUBLE,max_y DOUBLE,srs_id INTEGER);";
        private const string CREATE_FAILURES_TABLE_SQL = "CREATE Table Failures(Zoom int,X int64,Y int64,primary key(Zoom,X,Y));";
        private const string CREATE_GEOPACKAGETILES_VIEW_SQL = "CREATE VIEW @Name AS SELECT map.ROWID AS id,map.zoom_level AS zoom_level,map.tile_column AS tile_column,map.tile_row AS tile_row,images.tile_data AS tile_data FROM map JOIN images ON images.tile_id = map.tile_id;";
        private const string CREATE_IMAGES_INDEX_SQL = "CREATE UNIQUE INDEX images_id on images (tile_id);";
        private const string CREATE_IMAGES_TABLE_SQL = "CREATE TABLE images(tile_data BLOB,tile_id TEXT);";
        private const string CREATE_MAP_INDEX_SQL = "CREATE UNIQUE INDEX map_index on map (zoom_level, tile_column, tile_row);";
        private const string CREATE_MAP_TABLE_SQL = "CREATE TABLE map(zoom_level INTEGER,tile_column INTEGER,tile_row INTEGER,tile_id TEXT);";
        private const string CREATE_MBTILES_VIEW_SQL = "CREATE VIEW tiles AS SELECT map.zoom_level AS zoom_level,map.tile_column AS tile_column,map.tile_row AS tile_row,images.tile_data AS tile_data FROM map JOIN images ON images.tile_id = map.tile_id;";
        private const string CREATE_METADATA_INDEX_SQL = "CREATE UNIQUE INDEX name ON metadata (name);";
        private const string CREATE_METADATA_TABLE_SQL = "CREATE Table metadata(name nvarchar(64) primary key, value TEXT);";
        private const string CREATE_ORUXMAPS_ANDROID_METADATA_TABLE_SQL = "CREATE TABLE android_metadata (locale TEXT);";
        private const string CREATE_SQLITEDB_ANDROID_METADATA_TABLE_SQL = "CREATE TABLE android_metadata (locale TEXT);";
        private const string CREATE_SQLITEDB_INFO_TABLE_SQL = "CREATE TABLE info(minzoom,maxzoom);";
        private const string CREATE_SQLITEDB_S_FIELD_SQL = "ALTER TABLE tiles ADD 's' int DEFAULT 0;";
        private const string CREATE_SQLiteDB_TILES_INDEX_SQL = "CREATE INDEX IND on tiles (x,y,z);";
        private const string CREATE_SQLiteDB_TILES_TEMP_TABLE_SQL = "CREATE TABLE temp (x int, y int, z int, image blob, PRIMARY KEY (x,y,z));";
        private const string CREATE_SRS_TABLE_SQL = "CREATE TABLE gpkg_spatial_ref_sys (srs_name TEXT NOT NULL,srs_id INTEGER NOT NULL PRIMARY KEY,organization TEXT NOT NULL,organization_coordsys_id INTEGER NOT NULL,definition  TEXT NOT NULL,description TEXT);";
        private const string CREATE_TASKS_TABLE_SQL = "CREATE Table Tasks(ID char(32) primary key,TaskDBPath TEXT not null);";
        private const string CREATE_TILEMATRIX_TABLE_SQL = "CREATE TABLE gpkg_tile_matrix (table_name TEXT NOT NULL,zoom_level INTEGER NOT NULL,matrix_width INTEGER NOT NULL,matrix_height INTEGER NOT NULL,tile_width INTEGER NOT NULL,tile_height INTEGER NOT NULL,pixel_x_size DOUBLE NOT NULL,pixel_y_size DOUBLE NOT NULL);";
        private const string CREATE_TILEMATRIXSET_TABLE_SQL = "CREATE TABLE gpkg_tile_matrix_set (table_name TEXT NOT NULL PRIMARY KEY,srs_id INTEGER NOT NULL,min_x DOUBLE NOT NULL,min_y DOUBLE NOT NULL,max_x DOUBLE NOT NULL,max_y DOUBLE NOT NULL);";
        private const string CREATE_TILES_VIEW_SQL = "CREATE VIEW Tiles AS SELECT map.zoom_level AS Zoom,map.tile_column AS X,map.tile_row AS Y,images.tile_data AS Data FROM map JOIN images ON images.tile_id = map.tile_id;";
        private static readonly string DATABASE_PW;
        private const string DATE_FORMAT = "yy-MM-dd HH:mm:ss";
        private const string DELETE_ALL_FAILED_TILES_SQL = "DELETE FROM Failures";
        private const string DELETE_ALL_METADATA_SQL = "DELETE FROM metadata";
        private const string DELETE_FAILED_TILE_SQL = "DELETE FROM Failures WHERE zoom=@Zoom and x=@X and y=@Y";
        private const string DELETE_FAILURE_TILES_SQL = "delete from Failures";
        private const string DELETE_IMAGES_SQL = "DELETE FROM images WHERE tile_id in (SELECT tile_id FROM map WHERE zoom_level=@zoom_level)";
        private const string DELETE_MAP_SQL = "DELETE FROM map WHERE zoom_level=@zoom_level";
        private const string DELETE_METADATA_SQL = "DELETE FROM metadata WHERE Name=@Name";
        private const string DELETE_ONE_FAILED_TILES_SQL = "DELETE FROM Failures WHERE X=@X and Y=@Y and Zoom=@Zoom";
        private const string DELETE_TASK_INDEX_DB_TASKS_SQL = "DELETE FROM Tasks WHERE ID= @ID";
        private const string GET_BUNDLE_SQL = "SELECT Bundle FROM Bundles WHERE Zoom=@Zoom and BundleIndex=@BundleIndex";
        private const string GET_FAILED_COUNT_SQL = "SELECT count(*) FROM failures";
        private const string GET_FAILED_TILES_SQL = "SELECT * FROM failures";
        private const string GET_IMAGE_SQL = "SELECT Data FROM Tiles WHERE X={0} and Y={1} and Zoom={2}";
        private static readonly string GET_METADATA_ITEM_SQL;
        private const string GET_ONE_FAILED_TILES_SQL = "SELECT * FROM Failures Limit 1";
        private const string GET_SUCCESS_COUNT_SQL = "SELECT count(*) FROM map";
        private const string GET_SUCCESS_LEVEL_COUNT_SQL = "SELECT count(*) FROM map WHERE {0}";
        private const string GET_TASK_INDEX_DB_TASKS_SQL = "SELECT * FROM Tasks";
        private static object getTaskConnLock;
        private const string INSERT_ANDROID_METADATA_SQL = "INSERT or REPLACE Into android_metadata(locale) Values(\"zh_CN\");";
        private const string INSERT_CONTENTS_SQL = "INSERT or REPLACE Into gpkg_contents(table_name,data_type,identifier,description,last_change,min_x,min_y,max_x,max_y,srs_id) Values(@table_name,@data_type,@identifier,@description,@last_change,@min_x,@min_y,@max_x,@max_y,@srs_id);";
        private const string INSERT_FAILED_TILE_SQL = "INSERT or REPLACE INTO Failures(Zoom,X,Y) values(@Zoom,@X,@Y)";
        private const string INSERT_INFO_SQL = "INSERT or REPLACE Into info(minzoom,maxzoom) Values(@minzoom,@maxzoom);";
        private const string INSERT_METADATA_SQL = "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)";
        private const string INSERT_SRS_SQL = "INSERT or REPLACE Into gpkg_spatial_ref_sys(srs_name,srs_id,organization,organization_coordsys_id,definition,description) Values(@srs_name,@srs_id,@organization,@organization_coordsys_id,@definition,@description);";
        private const string INSERT_TILEMARTIX_SQL = "INSERT or REPLACE Into gpkg_tile_matrix(table_name,zoom_level,matrix_width,matrix_height,tile_width,tile_height,pixel_x_size,pixel_y_size) Values(@table_name,@zoom_level,@matrix_width,@matrix_height,@tile_width,@tile_height,@pixel_x_size,@pixel_y_size);";
        private const string INSERT_TILEMARTIXSET_SQL = "INSERT or REPLACE Into gpkg_tile_matrix_set(table_name,srs_id,min_x,min_y,max_x,max_y) Values(@table_name,@srs_id,@min_x,@min_y,@max_x,@max_y);";
        private const string INSERT_UPDATE_BUNDLE_SQL = "INSERT or Replace into Bundles(Zoom,BundleIndex,Bundle) values(@Zoom,@BundleIndex,@Bundle)";
        private const string INSERT_UPDATE_TASK_INDEX_DB_SQL = "INSERT or Replace into tasks(ID,TaskDBPath) values(@ID,@TaskDBPath)";
        private static object removeDownloadTaskLock;
        private static readonly string TASK_INDEX_DB_CONN_STRING;
        private const string TASK_INDEX_DB_NAME = "Download/TASK_INDEX.azdb";
        private static Dictionary<string, SQLiteConnection> taskConns;
        private static SQLiteConnection taskIndexDBPathConn;
        private const string TILE_EXIST_SQL = "select exists(select Zoom,X,Y from Tiles where Zoom=@Zoom and Y=@Y and X=@X)";
        private const string UPDATE_MAP_TO_TMS_PLUS_SQL = "UPDATE map SET tile_row=tile_row+1000000 WHERE zoom_level={0}";
        private const string UPDATE_MAP_TO_TMS_SQL = "UPDATE map SET tile_row={0}-tile_row WHERE zoom_level={1}";
        private const string UPDATE_ORUXMAP_X_SQL1 = "UPDATE tiles SET x=x+1000000;";
        private const string UPDATE_ORUXMAP_X_SQL2 = "UPDATE tiles SET x=x-1000000-{0} WHERE z={1};";
        private const string UPDATE_ORUXMAP_Y_SQL1 = "UPDATE tiles SET y=y+1000000;";
        private const string UPDATE_ORUXMAP_Y_SQL2 = "UPDATE tiles SET y=y-1000000-{0} WHERE z={1};";
        private const string UPDATE_ORUXMAP_Z_SQL1 = "UPDATE tiles SET z=z+100;";
        private const string UPDATE_ORUXMAP_Z_SQL2 = "UPDATE tiles SET z=z-99;";
        private const string UPDATE_SQLITEDB_Z_SQL = "UPDATE tiles SET z=17-z;";
        private const string UPDATE_TASK_STATUS_SQL = "UPDATE metadata set Value=@Status WHERE Name ='Status'";
        private const string UPDATE_TASK_THREADS_SQL = "UPDATE metadata set Value=@ThreadCount WHERE Name ='ThreadCount'";

        static AZDBSQLiteHelper()
        {
            DATABASE_PW = EncryptString.ThisIsLegalString("jztU+R63Ke4=");
            TASK_INDEX_DB_CONN_STRING = string.Format("Data Source=\"{0}\";FailIfMissing=False;Page Size=32768;Pooling=True", "Download/TASK_INDEX.azdb");
            GET_METADATA_ITEM_SQL = "SELECT Value FROM metadata WHERE Name = @Name";
            taskConns = new Dictionary<string, SQLiteConnection>();
            getTaskConnLock = new object();
            removeDownloadTaskLock = new object();
        }

        internal static bool AddDataToContentsTable(string dbPath, object name, object dataType, object identifier, object description, object lastChange, double minX, double minY, double maxX, double maxY, int srsID)
        {
            SQLiteConnection aZDBFileConn = GetAZDBFileConn(dbPath);
            SQLiteParameter[] parameters = new SQLiteParameter[] { new SQLiteParameter("@table_name", name), new SQLiteParameter("@data_type", dataType), new SQLiteParameter("@identifier", identifier), new SQLiteParameter("@description", description), new SQLiteParameter("@last_change", lastChange), new SQLiteParameter("@min_x", minX), new SQLiteParameter("@min_y", minY), new SQLiteParameter("@max_x", maxX), new SQLiteParameter("@max_y", maxY), new SQLiteParameter("@srs_id", srsID) };
            return SQLiteHelper.ExcuteNoneQuery(aZDBFileConn, "INSERT or REPLACE Into gpkg_contents(table_name,data_type,identifier,description,last_change,min_x,min_y,max_x,max_y,srs_id) Values(@table_name,@data_type,@identifier,@description,@last_change,@min_x,@min_y,@max_x,@max_y,@srs_id);", parameters, null);
        }

        internal static bool AddDataToSQLiteDBAndroidMetadata(string dbPath)
        {
            return SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "INSERT or REPLACE Into android_metadata(locale) Values(\"zh_CN\");", null, null);
        }

        internal static bool AddDataToSQLiteDBInfo(string dbPath, int minZoom, int maxZoom)
        {
            SQLiteConnection aZDBFileConn = GetAZDBFileConn(dbPath);
            SQLiteParameter[] parameters = new SQLiteParameter[] { new SQLiteParameter("@minzoom", minZoom), new SQLiteParameter("@maxzoom", maxZoom) };
            return SQLiteHelper.ExcuteNoneQuery(aZDBFileConn, "INSERT or REPLACE Into info(minzoom,maxzoom) Values(@minzoom,@maxzoom);", parameters, null);
        }

        internal static bool AddDataToSRSTable(string dbPath, object name, int id, object organization, int organizationCoordsysID, object definition, object description)
        {
            SQLiteConnection aZDBFileConn = GetAZDBFileConn(dbPath);
            SQLiteParameter[] parameters = new SQLiteParameter[] { new SQLiteParameter("@srs_name", name), new SQLiteParameter("@srs_id", id), new SQLiteParameter("@organization", organization), new SQLiteParameter("@organization_coordsys_id", organizationCoordsysID), new SQLiteParameter("@definition", definition), new SQLiteParameter("@description", description) };
            return SQLiteHelper.ExcuteNoneQuery(aZDBFileConn, "INSERT or REPLACE Into gpkg_spatial_ref_sys(srs_name,srs_id,organization,organization_coordsys_id,definition,description) Values(@srs_name,@srs_id,@organization,@organization_coordsys_id,@definition,@description);", parameters, null);
        }

        internal static bool AddDataToTileMatrixSetTable(string dbPath, object name, int srsID, double minX, double minY, double maxX, double maxY)
        {
            SQLiteConnection aZDBFileConn = GetAZDBFileConn(dbPath);
            SQLiteParameter[] parameters = new SQLiteParameter[] { new SQLiteParameter("@table_name", name), new SQLiteParameter("@srs_id", srsID), new SQLiteParameter("@min_x", minX), new SQLiteParameter("@min_y", minY), new SQLiteParameter("@max_x", maxX), new SQLiteParameter("@max_y", maxY) };
            return SQLiteHelper.ExcuteNoneQuery(aZDBFileConn, "INSERT or REPLACE Into gpkg_tile_matrix_set(table_name,srs_id,min_x,min_y,max_x,max_y) Values(@table_name,@srs_id,@min_x,@min_y,@max_x,@max_y);", parameters, null);
        }

        internal static bool AddDataToTileMatrixTable(string dbPath, object name, int zoomLevel, long martixWidth, long martixHeight, long tileWidth, long tileHeight, double double_0, double double_1)
        {
            SQLiteConnection aZDBFileConn = GetAZDBFileConn(dbPath);
            SQLiteParameter[] parameters = new SQLiteParameter[] { new SQLiteParameter("@table_name", name), new SQLiteParameter("@zoom_level", zoomLevel), new SQLiteParameter("@matrix_width", martixWidth), new SQLiteParameter("@matrix_height", martixHeight), new SQLiteParameter("@tile_width", tileWidth), new SQLiteParameter("@tile_height", tileHeight), new SQLiteParameter("@pixel_x_size", double_0), new SQLiteParameter("@pixel_y_size", double_1) };
            return SQLiteHelper.ExcuteNoneQuery(aZDBFileConn, "INSERT or REPLACE Into gpkg_tile_matrix(table_name,zoom_level,matrix_width,matrix_height,tile_width,tile_height,pixel_x_size,pixel_y_size) Values(@table_name,@zoom_level,@matrix_width,@matrix_height,@tile_width,@tile_height,@pixel_x_size,@pixel_y_size);", parameters, null);
        }

        //private static void AddMetadata(SQLiteConnection conn, object task)
        //{
        //    if (conn == null)
        //    {
        //        conn = GetAZDBFileConn(task.dbPath);
        //    }
        //    SQLiteParameter[] parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "Bounds"), new SQLiteParameter("@Value", task.ViewBounds.ToString()) };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, null);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "EpsgCode"), new SQLiteParameter("@Value", task.MapProvider.Projection.EpsgCode) };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, null);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "MapName"), new SQLiteParameter("@Value", task.MapName) };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, null);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "Levels"), new SQLiteParameter("@Value", task.Levels.ToString<int>(",")) };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, null);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "LevelTilesMetadatas"), new SQLiteParameter("@Value", Base64Util.ConvertObjToString(task.LevelTilesMetadatas)) };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, null);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "TileTotal"), new SQLiteParameter("@Value", task.TileTotal) };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, null);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "ThreadCount"), new SQLiteParameter("@Value", task.ThreadCount) };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, null);
        //    if (task.ExportParam != null)
        //    {
        //        parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "ExportParam"), new SQLiteParameter("@Value", Base64Util.ConvertObjToString(task.ExportParam)) };
        //        SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, null);
        //    }
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "Markers"), new SQLiteParameter("@Value", Base64Util.ConvertObjToString(task.Markers)) };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, null);
        //    if ((task.SheetLineTiles != null) && (task.SheetLineTiles.Count > 0))
        //    {
        //        parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "SheetLineTiles"), new SQLiteParameter("@Value", Base64Util.ConvertObjToString(task.SheetLineTiles)) };
        //        SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, null);
        //    }
        //}

        internal static void AddMetadataItemToDB(string dbFile, object name, object value)
        {
            SQLiteConnection aZDBFileConn = GetAZDBFileConn(dbFile);
            SQLiteParameter[] parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", name), new SQLiteParameter("@Value", value) };
            SQLiteHelper.ExcuteNoneQuery(aZDBFileConn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, null);
        }

        //private static void AddOrUpdateTask(SQLiteConnection conn, DownloadTask task, SQLiteTransaction transAction = null)
        //{
        //    if (conn == null)
        //    {
        //        conn = GetAZDBFileConn(task.dbPath);
        //    }
        //    SQLiteParameter[] parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "ID"), new SQLiteParameter("@Value", task.ID) };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, transAction);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "TaskName"), new SQLiteParameter("@Value", task.Name) };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, transAction);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "CreateTime"), new SQLiteParameter("@Value", task.CreateTime.ToString("yy-MM-dd HH:mm:ss")) };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, transAction);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "TaskDBPath"), new SQLiteParameter("@Value", task.dbPath) };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, transAction);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "Status"), new SQLiteParameter("@Value", task.DisplayStatus) };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, transAction);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "TotalTime"), new SQLiteParameter("@Value", task.TotalTime) };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, transAction);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "DownloadFailedTilesOnly"), new SQLiteParameter("@Value", task.DownloadFailedTilesOnly ? "true" : "false") };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, transAction);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "IsCompress"), new SQLiteParameter("@Value", task.IsCompress) };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, transAction);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "CompressLevel"), new SQLiteParameter("@Value", task.CompressLevel) };
        //    SQLiteHelper.ExcuteNoneQuery(conn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, transAction);
        //}

        //internal static void AddTaskToDB(DownloadTask task, bool isNewTask = true)
        //{
        //    SQLiteHelper.ExcuteNoneQuery(GetTaskIndexDBConn, "INSERT or Replace into tasks(ID,TaskDBPath) values(@ID,@TaskDBPath)", new SQLiteParameter[] { new SQLiteParameter("@ID", task.ID), new SQLiteParameter("@TaskDBPath", task.dbPath) }, null);
        //    if (isNewTask)
        //    {
        //        AddMetadata(GetAZDBFileConn(task.dbPath), task);
        //        AddOrUpdateTask(GetAZDBFileConn(task.dbPath), task, null);
        //    }
        //}

        internal static void ClearPassword(string dbFile)
        {
            GetAZDBFileConn(dbFile).ChangePassword("");
        }

        //internal static bool CopyAZDBTilesToOruxMaps(string dbPath, object downloadTaskName, List<int> exportLevels, Hashtable levelTilesBuilders)
        //{
        //    SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "CREATE TABLE temp (x int, y int, z int, image blob, PRIMARY KEY (x,y,z));", null, null);
        //    SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "INSERT INTO temp SELECT X AS x,Y AS y,Zoom AS z,Data AS image FROM tiles ", null, null);
        //    DeleteView(dbPath, "Tiles");
        //    DeleteTable(dbPath, "images");
        //    DeleteTable(dbPath, "map");
        //    SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "ALTER TABLE temp RENAME TO tiles", null, null);
        //    SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "UPDATE tiles SET x=x+1000000;", null, null);
        //    SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "UPDATE tiles SET y=y+1000000;", null, null);
        //    foreach (int num in exportLevels)
        //    {
        //        LevelTilesBuilder builder = (LevelTilesBuilder)levelTilesBuilders[downloadTaskName + num];
        //        SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), string.Format("UPDATE tiles SET x=x-1000000-{0} WHERE z={1};", builder.long_0, num), null, null);
        //        SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), string.Format("UPDATE tiles SET y=y-1000000-{0} WHERE z={1};", builder.long_2, num), null, null);
        //    }
        //    return SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "CREATE INDEX IND on tiles (x,y,z);", null, null);
        //}

        internal static bool CopyAZDBTilesToSQLiteDB(string dbPath)
        {
            SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "CREATE TABLE temp (x int, y int, z int, image blob, PRIMARY KEY (x,y,z));", null, null);
            SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "INSERT INTO temp SELECT X AS x,Y AS y,Zoom AS z,Data AS image FROM tiles ", null, null);
            DeleteView(dbPath, "Tiles");
            DeleteTable(dbPath, "images");
            DeleteTable(dbPath, "map");
            SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "ALTER TABLE temp RENAME TO tiles", null, null);
            SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "UPDATE tiles SET z=17-z;", null, null);
            SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "ALTER TABLE tiles ADD 's' int DEFAULT 0;", null, null);
            return SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "CREATE INDEX IND on tiles (x,y,z);", null, null);
        }

        internal static bool CreateGeoPackageContentsTable(string dbPath)
        {
            return SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "CREATE TABLE gpkg_contents (table_name TEXT NOT NULL PRIMARY KEY,data_type TEXT NOT NULL,identifier TEXT UNIQUE,description TEXT DEFAULT '',last_change DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),min_x DOUBLE,min_y DOUBLE,max_x DOUBLE,max_y DOUBLE,srs_id INTEGER);", null, null);
        }

        internal static bool CreateGeoPackageSRSTable(string dbPath)
        {
            return SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "CREATE TABLE gpkg_spatial_ref_sys (srs_name TEXT NOT NULL,srs_id INTEGER NOT NULL PRIMARY KEY,organization TEXT NOT NULL,organization_coordsys_id INTEGER NOT NULL,definition  TEXT NOT NULL,description TEXT);", null, null);
        }

        internal static bool CreateGeoPackageTileMatrixSetTable(string dbPath)
        {
            return SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "CREATE TABLE gpkg_tile_matrix_set (table_name TEXT NOT NULL PRIMARY KEY,srs_id INTEGER NOT NULL,min_x DOUBLE NOT NULL,min_y DOUBLE NOT NULL,max_x DOUBLE NOT NULL,max_y DOUBLE NOT NULL);", null, null);
        }

        internal static bool CreateGeoPackageTileMatrixTable(string dbPath)
        {
            return SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "CREATE TABLE gpkg_tile_matrix (table_name TEXT NOT NULL,zoom_level INTEGER NOT NULL,matrix_width INTEGER NOT NULL,matrix_height INTEGER NOT NULL,tile_width INTEGER NOT NULL,tile_height INTEGER NOT NULL,pixel_x_size DOUBLE NOT NULL,pixel_y_size DOUBLE NOT NULL);", null, null);
        }

        internal static bool CreateMBTilesView(string dbPath)
        {
            return SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "CREATE VIEW tiles AS SELECT map.zoom_level AS zoom_level,map.tile_column AS tile_column,map.tile_row AS tile_row,images.tile_data AS tile_data FROM map JOIN images ON images.tile_id = map.tile_id;", null, null);
        }

        internal static bool CreateOruxMapsMetaTable(string dbPath)
        {
            return SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "CREATE TABLE android_metadata (locale TEXT);", null, null);
        }

        internal static bool CreateSQLiteDBMetaTable(string dbPath)
        {
            SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "CREATE TABLE android_metadata (locale TEXT);", null, null);
            return SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "CREATE TABLE info(minzoom,maxzoom);", null, null);
        }

        internal static bool CreateTilesView(string dbPath, string name)
        {
            SQLiteConnection aZDBFileConn = GetAZDBFileConn(dbPath);
            string sql = "CREATE VIEW @Name AS SELECT map.ROWID AS id,map.zoom_level AS zoom_level,map.tile_column AS tile_column,map.tile_row AS tile_row,images.tile_data AS tile_data FROM map JOIN images ON images.tile_id = map.tile_id;".Replace("@Name", name);
            return SQLiteHelper.ExcuteNoneQuery(aZDBFileConn, sql, null, null);
        }

        //internal static long DeleteFailedTile(string dbPath, DownloadTile tile)
        //{
        //    SQLiteParameter[] parameters = new SQLiteParameter[] { new SQLiteParameter("@Zoom", tile.Z), new SQLiteParameter("@X", tile.X), new SQLiteParameter("@Y", tile.Y) };
        //    return long.Parse(SQLiteHelper.ExecuteScalar(GetAZDBFileConn(dbPath), "DELETE FROM Failures WHERE zoom=@Zoom and x=@X and y=@Y", parameters).ToString());
        //}

        internal static void DeleteFailureTiles(string dbPath)
        {
            SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "delete from Failures", null, null);
        }

        internal static bool DeleteTable(string dbPath, string tableName)
        {
            return SQLiteHelper.DropTable(GetAZDBFileConn(dbPath), tableName);
        }

        internal static bool DeleteTilesByLevel(string dbPath, int level)
        {
            return SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "DELETE FROM images WHERE tile_id in (SELECT tile_id FROM map WHERE zoom_level=@zoom_level)", new SQLiteParameter[] { new SQLiteParameter("@zoom_level", level) }, null);
        }

        internal static bool DeleteView(string dbPath, string viewName)
        {
            return SQLiteHelper.DropView(GetAZDBFileConn(dbPath), viewName);
        }

        internal static void Dispose()
        {
            if (taskIndexDBPathConn != null)
            {
                taskIndexDBPathConn.Close();
            }
            foreach (KeyValuePair<string, SQLiteConnection> pair in taskConns)
            {
                if (pair.Value != null)
                {
                    pair.Value.Close();
                }
            }
            taskConns = null;
        }

        internal static void Dispose(string dbFile)
        {
            if (taskConns.ContainsKey(dbFile))
            {
                foreach (KeyValuePair<string, SQLiteConnection> pair in taskConns)
                {
                    if (pair.Key == dbFile)
                    {
                        pair.Value.Close();
                    }
                }
                taskConns.Remove(dbFile);
            }
        }

        //internal static Queue<DownloadTile> GetAllFailedTilesFromDB(string dbPath)
        //{
        //    SQLiteConnection aZDBFileConn = GetAZDBFileConn(dbPath);
        //    lock (aZDBFileConn)
        //    {
        //        DataTable table = SQLiteHelper.ExecuteDataTable(aZDBFileConn, "SELECT * FROM failures", null);
        //        Queue<DownloadTile> queue = new Queue<DownloadTile>();
        //        if (table.Rows.Count > 0)
        //        {
        //            DownloadTile item = null;
        //            foreach (DataRow row in table.Rows)
        //            {
        //                item = new DownloadTile
        //                {
        //                    X = long.Parse(row["X"].ToString()),
        //                    Y = long.Parse(row["Y"].ToString()),
        //                    Z = int.Parse(row["Zoom"].ToString())
        //                };
        //                item.isFailTile = true;
        //                queue.Enqueue(item);
        //            }
        //            return queue;
        //        }
        //        return null;
        //    }
        //}

        //internal static List<DownloadTask> GetAllTasksFromDB()
        //{
        //    List<DownloadTask> list = new List<DownloadTask>();
        //    DataTable table = SQLiteHelper.ExecuteDataTable(GetTaskIndexDBConn, "SELECT * FROM Tasks", null);
        //    if (table != null)
        //    {
        //        foreach (DataRow row in table.Rows)
        //        {
        //            try
        //            {
        //                DownloadTask task = new DownloadTask
        //                {
        //                    ID = row["ID"].ToString(),
        //                    dbPath = row["TaskDBPath"].ToString().Trim()
        //                };
        //                if (!string.IsNullOrEmpty(task.dbPath) && new FileInfo(task.dbPath).Exists)
        //                {
        //                    if (!GetTask(task))
        //                    {
        //                        RemoveTaskFromDB(task.ID);
        //                    }
        //                    else
        //                    {
        //                        if (task.MapProvider == null)
        //                        {
        //                            RemoveTaskFromDB(task.ID);
        //                        }
        //                        list.Add(task);
        //                    }
        //                }
        //                else
        //                {
        //                    RemoveTaskFromDB(task.ID);
        //                }
        //            }
        //            catch (Exception exception)
        //            {
        //                LogUtil.Error("无法获取切片下载任务", exception);
        //            }
        //        }
        //    }
        //    return list;
        //}

        internal static SQLiteConnection GetAZDBFileConn(string dbPath)
        {
            lock (getTaskConnLock)
            {
                if (taskConns.ContainsKey(dbPath))
                {
                    return taskConns[dbPath];
                }
                bool flag2 = false;
                if (File.Exists(dbPath))
                {
                    flag2 = true;
                }
                else
                {
                    string directoryName = Path.GetDirectoryName(dbPath);
                    if (!Directory.Exists(directoryName))
                    {
                        Directory.CreateDirectory(directoryName);
                    }
                }
                SQLiteConnection sQLiteConn = SQLiteHelper.GetSQLiteConn(dbPath);
                if (sQLiteConn != null)
                {
                    taskConns.Add(dbPath, sQLiteConn);
                    if (!flag2)
                    {
                        string sql = "CREATE Table metadata(name nvarchar(64) primary key, value TEXT);CREATE UNIQUE INDEX name ON metadata (name);CREATE TABLE images(tile_data BLOB,tile_id TEXT);CREATE UNIQUE INDEX images_id on images (tile_id);CREATE TABLE map(zoom_level INTEGER,tile_column INTEGER,tile_row INTEGER,tile_id TEXT);CREATE UNIQUE INDEX map_index on map (zoom_level, tile_column, tile_row);CREATE VIEW Tiles AS SELECT map.zoom_level AS Zoom,map.tile_column AS X,map.tile_row AS Y,images.tile_data AS Data FROM map JOIN images ON images.tile_id = map.tile_id;CREATE Table Failures(Zoom int,X int64,Y int64,primary key(Zoom,X,Y));CREATE Table Bundles(Zoom int,BundleIndex int64,Bundle BLOB,primary key(Zoom,BundleIndex) );";
                        SQLiteHelper.ExcuteNoneQuery(sQLiteConn, sql, null, null);
                    }
                }
                return sQLiteConn;
            }
        }

        //internal static TilesBundle GetBundleFromDB(DownloadTask task, int zoom, long bundleIndex)
        //{
        //    DataTable table = SQLiteHelper.ExecuteDataTable(GetAZDBFileConn(task.dbPath), "SELECT Bundle FROM Bundles WHERE Zoom=@Zoom and BundleIndex=@BundleIndex", new SQLiteParameter[] { new SQLiteParameter("@Zoom", zoom), new SQLiteParameter("@BundleIndex", bundleIndex) });
        //    if ((table == null) || (table.Rows.Count == 0))
        //    {
        //        return null;
        //    }
        //    DataRow row = table.Rows[0];
        //    byte[] data = row[0] as byte[];
        //    if ((data == null) || (data.Length == 0))
        //    {
        //        return null;
        //    }
        //    object obj2 = Base64Util.ConvertByteArrayToObj(data);
        //    if (obj2 == null)
        //    {
        //        return null;
        //    }
        //    return (obj2 as TilesBundle);
        //}

        internal static long GetFailedCountFromDB(string dbPath)
        {
            return long.Parse(SQLiteHelper.ExecuteScalar(GetAZDBFileConn(dbPath), "SELECT count(*) FROM failures", null).ToString());
        }

        //internal static byte[] GetImageFromDB(string dbPath, GPoint pos, int zoom)
        //{
        //    using (DbCommand command = GetAZDBFileConn(dbPath).CreateCommand())
        //    {
        //        command.CommandText = string.Format("SELECT Data FROM Tiles WHERE X={0} and Y={1} and Zoom={2}", pos.X, pos.Y, zoom);
        //        using (DbDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
        //        {
        //            if (reader.Read())
        //            {
        //                byte[] buffer = new byte[reader.GetBytes(0, 0L, null, 0, 0)];
        //                reader.GetBytes(0, 0L, buffer, 0, buffer.Length);
        //                return buffer;
        //            }
        //        }
        //    }
        //    return null;
        //}

        internal static long GetLevelCountFromDB(string dbPath, int level)
        {
            string str = string.Empty + "zoom_level=" + level;
            return long.Parse(SQLiteHelper.ExecuteScalar(GetAZDBFileConn(dbPath), string.Format("SELECT count(*) FROM map WHERE {0}", str), null).ToString());
        }

        internal static long GetLevelsCountFromDB(string dbPath, List<int> levels)
        {
            string str = string.Empty;
            foreach (int num in levels)
            {
                object obj2 = str;
                str = string.Concat(new object[] { obj2, "zoom_level=", num, " or " });
            }
            str = str.Substring(0, str.Length - 3);
            return long.Parse(SQLiteHelper.ExecuteScalar(GetAZDBFileConn(dbPath), string.Format("SELECT count(*) FROM map WHERE {0}", str), null).ToString());
        }

        public static string GetMetadataItemFromDB(string dbPath, string proName)
        {
            SQLiteParameter[] parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", proName) };
            object obj2 = SQLiteHelper.ExecuteScalar(GetAZDBFileConn(dbPath), GET_METADATA_ITEM_SQL, parameters);
            if (obj2 == null)
            {
                return string.Empty;
            }
            return obj2.ToString();
        }

        //internal static long GetPartLevelCountFromDB(string dbPath, int level, object startTile, object endTile)
        //{
        //    string str = string.Format("zoom_level={0}", level);
        //    if ((startTile != null) && (endTile != null))
        //    {
        //        str = str + string.Format(" and tile_column>{0} and tile_row>{1} and tile_column<{2} and tile_row<{3}", new object[] { startTile.X, startTile.Y, endTile.X, endTile.Y });
        //    }
        //    return long.Parse(SQLiteHelper.ExecuteScalar(GetAZDBFileConn(dbPath), string.Format("SELECT count(*) FROM map WHERE {0}", str), null).ToString());
        //}

        internal static long GetSuccessCountFromDB(string dbPath)
        {
            return long.Parse(SQLiteHelper.ExecuteScalar(GetAZDBFileConn(dbPath), "SELECT count(*) FROM map", null).ToString());
        }

        //private static bool GetTask(DownloadTask task)
        //{
        //    try
        //    {
        //        task.ID = GetMetadataItemFromDB(task.dbPath, "ID");
        //        task.Name = GetMetadataItemFromDB(task.dbPath, "TaskName");
        //        task.MapName = GetMetadataItemFromDB(task.dbPath, "MapName");
        //        if ((!string.IsNullOrEmpty(task.ID) && !string.IsNullOrEmpty(task.Name)) && !string.IsNullOrEmpty(task.MapName))
        //        {
        //            string metadataItemFromDB = GetMetadataItemFromDB(task.dbPath, "Bounds");
        //            if (!string.IsNullOrEmpty(metadataItemFromDB))
        //            {
        //                task.ViewBounds = RectLatLng.FromString(metadataItemFromDB);
        //            }
        //            string str12 = GetMetadataItemFromDB(task.dbPath, "FailedCount");
        //            if (!string.IsNullOrEmpty(str12))
        //            {
        //                task.FailedCount = long.Parse(str12);
        //            }
        //            string str14 = GetMetadataItemFromDB(task.dbPath, "SuccessCount");
        //            if (!string.IsNullOrEmpty(str14))
        //            {
        //                task.SuccessCount = long.Parse(str14);
        //            }
        //            string str13 = GetMetadataItemFromDB(task.dbPath, "CurrentZ");
        //            if (!string.IsNullOrEmpty(str13))
        //            {
        //                task.QueryZ = int.Parse(str13);
        //                task.WritedZ = task.QueryZ;
        //            }
        //            string str3 = GetMetadataItemFromDB(task.dbPath, "CurrentBundleIndex");
        //            if (!string.IsNullOrEmpty(str3))
        //            {
        //                task.QueryBundleIndex = long.Parse(str3);
        //                task.WritedBundleIndex = task.QueryBundleIndex;
        //            }
        //            string str6 = GetMetadataItemFromDB(task.dbPath, "CurrentTileIndex");
        //            if (!string.IsNullOrEmpty(str6))
        //            {
        //                task.QueryBundleTileIndex = long.Parse(str6);
        //                task.WritedBundleTileIndex = task.QueryBundleTileIndex;
        //            }
        //            string str15 = GetMetadataItemFromDB(task.dbPath, "LevelTilesMetadatas");
        //            if (!string.IsNullOrEmpty(str15))
        //            {
        //                task.LevelTilesMetadatas = Base64Util.ConvertStringToObj(str15) as List<LevelTilesMetadata>;
        //            }
        //            string str10 = GetMetadataItemFromDB(task.dbPath, "CreateTime");
        //            if (!string.IsNullOrEmpty(str10))
        //            {
        //                task.CreateTime = DateTime.Parse(str10);
        //            }
        //            string str5 = GetMetadataItemFromDB(task.dbPath, "Levels");
        //            if (!string.IsNullOrEmpty(str5))
        //            {
        //                task.Levels = ListUtil.FromString<int>(str5, ",");
        //            }
        //            string str7 = GetMetadataItemFromDB(task.dbPath, "TotalTime");
        //            if (!string.IsNullOrEmpty(str7))
        //            {
        //                task.TotalTime = TimeSpan.Parse(str7);
        //            }
        //            else
        //            {
        //                task.TotalTime = new TimeSpan();
        //            }
        //            string str8 = GetMetadataItemFromDB(task.dbPath, "TileTotal");
        //            if (!string.IsNullOrEmpty(str8))
        //            {
        //                task.TileTotal = long.Parse(str8);
        //            }
        //            string str = GetMetadataItemFromDB(task.dbPath, "ThreadCount");
        //            if (!string.IsNullOrEmpty(str) && NumberUtil.IsInt(str))
        //            {
        //                task.ThreadCount = int.Parse(str);
        //            }
        //            bool result = false;
        //            bool.TryParse(GetMetadataItemFromDB(task.dbPath, "DownloadFailedTilesOnly"), out result);
        //            task.DownloadFailedTilesOnly = result;
        //            string str9 = GetMetadataItemFromDB(task.dbPath, "ExportParam");
        //            if (!string.IsNullOrEmpty(str9))
        //            {
        //                task.ExportParam = Base64Util.ConvertStringToObj(str9) as ExportParam;
        //            }
        //            string str2 = GetMetadataItemFromDB(task.dbPath, "Markers");
        //            if (!string.IsNullOrEmpty(str2))
        //            {
        //                task.Markers = Base64Util.ConvertStringToObj(str2) as List<Marker>;
        //            }
        //            string str11 = GetMetadataItemFromDB(task.dbPath, "IsCompress");
        //            if (!string.IsNullOrEmpty(str11))
        //            {
        //                bool flag3 = false;
        //                bool.TryParse(str11, out flag3);
        //                task.IsCompress = flag3;
        //            }
        //            string s = GetMetadataItemFromDB(task.dbPath, "CompressLevel");
        //            if (!string.IsNullOrEmpty(str12))
        //            {
        //                int num = 0x4b;
        //                int.TryParse(s, out num);
        //                task.CompressLevel = num;
        //            }
        //            string str4 = GetMetadataItemFromDB(task.dbPath, "SheetLineTiles");
        //            if (!string.IsNullOrEmpty(str4))
        //            {
        //                task.SheetLineTiles = Base64Util.ConvertStringToObj(str4) as List<SheetLineTile>;
        //            }
        //            DownloadDisplayStatus cOMPLETED = DownloadDisplayStatus.COMPLETED;
        //            Enum.TryParse<DownloadDisplayStatus>(GetMetadataItemFromDB(task.dbPath, "Status"), out cOMPLETED);
        //            task.DisplayStatus = cOMPLETED;
        //            RectifyTask(ref task);
        //            return true;
        //        }
        //        return false;
        //    }
        //    catch (Exception exception)
        //    {
        //        LogUtil.Error("获取任务信息失败", exception);
        //        return false;
        //    }
        //}

        //internal static bool GetTaskFromFile(string taskFile, out DownloadTask task)
        //{
        //    bool flag;
        //    task = new DownloadTask();
        //    task.dbPath = taskFile;
        //    if (flag = GetTask(task))
        //    {
        //        SQLiteHelper.ExcuteNoneQuery(GetTaskIndexDBConn, "INSERT or Replace into tasks(ID,TaskDBPath) values(@ID,@TaskDBPath)", new SQLiteParameter[] { new SQLiteParameter("@ID", task.ID), new SQLiteParameter("@TaskDBPath", task.dbPath) }, null);
        //    }
        //    return flag;
        //}

        //internal static long GetTilesCount(string dbPath, DownloadTile startTile, DownloadTile endTile, long maxRecordCount = -1L)
        //{
        //    if ((startTile == null) || (endTile == null))
        //    {
        //        return 0L;
        //    }
        //    StringBuilder builder = new StringBuilder();
        //    builder.Append(string.Format("select count(*) as count from map where zoom_level={0} and (", startTile.Z));
        //    if (startTile.Y == endTile.Y)
        //    {
        //        builder.Append(string.Format("tile_row={0} and tile_column>={1} and tile_column<={2})", startTile.Y, startTile.X, endTile.X));
        //    }
        //    else
        //    {
        //        builder.Append(string.Format("tile_row={0} and tile_column>={1} or tile_row>{2} and tile_row<{3} or tile_row={4} and tile_column<={5})", new object[] { startTile.Y, startTile.X, startTile.Y, endTile.Y, endTile.Y, endTile.X }));
        //    }
        //    if (maxRecordCount > 0L)
        //    {
        //        builder.Append(string.Format(" limit 0,{0}", maxRecordCount));
        //    }
        //    return long.Parse(SQLiteHelper.ExecuteScalar(GetAZDBFileConn(dbPath), builder.ToString(), null).ToString());
        //}

        //public static void RebuildLevelMetadatas(DownloadTask task)
        //{
        //    task.LevelTilesMetadatas = new List<LevelTilesMetadata>();
        //    foreach (int num in task.Levels)
        //    {
        //        LevelTilesMetadata item = new LevelTilesMetadata
        //        {
        //            Z = num,
        //            TileSize = GetLevelCountFromDB(task.dbPath, num),
        //            BundleSize = 1L
        //        };
        //        task.LevelTilesMetadatas.Add(item);
        //    }
        //}

        //public static bool RectifyOldVersionTask(DownloadTask task)
        //{
        //    try
        //    {
        //        long num = 0L;
        //        long num2 = 0L;
        //        string metadataItemFromDB = GetMetadataItemFromDB(task.dbPath, "CurrentX");
        //        string s = GetMetadataItemFromDB(task.dbPath, "CurrentY");
        //        string str3 = GetMetadataItemFromDB(task.dbPath, "CurrentZ");
        //        if (((metadataItemFromDB != null) && (s != null)) && (str3 != null))
        //        {
        //            int z = int.Parse(str3);
        //            long num4 = long.Parse(s);
        //            long num7 = long.Parse(metadataItemFromDB);
        //            if ((task.LevelTilesMetadatas == null) || (task.LevelTilesMetadatas.Count == 0))
        //            {
        //                return false;
        //            }
        //            if (z > task.Levels[task.Levels.Count - 1])
        //            {
        //                RemoveMetaDataItem("X", task);
        //                RemoveMetaDataItem("Y", task);
        //                task.QueryBundleIndex = task.GetLevelTilesMetaData(task.Levels[task.Levels.Count - 1]).BundleSize;
        //                return true;
        //            }
        //            LevelTilesMetadata levelTilesMetaData = task.GetLevelTilesMetaData(z);
        //            if (levelTilesMetaData == null)
        //            {
        //                return false;
        //            }
        //            for (int i = 0; i < levelTilesMetaData.BundleSize; i++)
        //            {
        //                TileSegment segment;
        //                TilesBundle bundle = GetBundleFromDB(task, z, (long)i);
        //                num2 = 0L;
        //                for (int j = 0; j < bundle.TileSegments.Count; j++)
        //                {
        //                    segment = bundle.TileSegments[j];
        //                    if ((num4 == segment.Row) && (num7 <= segment.EndColumn))
        //                    {
        //                        goto Label_0177;
        //                    }
        //                    num2 += segment.TileSize;
        //                }
        //                continue;
        //                Label_0177:
        //                num = i;
        //                if (num7 >= segment.StartColumn)
        //                {
        //                    num2 += num7 - segment.StartColumn;
        //                }
        //            }
        //            RemoveMetaDataItem("X", task);
        //            RemoveMetaDataItem("Y", task);
        //            task.QueryBundleIndex = num;
        //            task.QueryBundleTileIndex = num2;
        //        }
        //        return true;
        //    }
        //    catch
        //    {
        //        return false;
        //    }
        //}

        //internal static void RectifyTask(ref DownloadTask task)
        //{
        //    if (task.QueryZ == 0)
        //    {
        //        task.QueryZ = task.Levels[0];
        //        task.WritedZ = task.QueryZ;
        //    }
        //    if ((task.Levels.Count > 0) && ((task.LevelTilesMetadatas == null) || (task.LevelTilesMetadatas.Count == 0)))
        //    {
        //        new GridTilesCalculator().CaculateTiles(task, false);
        //        RectifyOldVersionTask(task);
        //    }
        //    else
        //    {
        //        long num = 0L;
        //        foreach (LevelTilesMetadata metadata in task.LevelTilesMetadatas)
        //        {
        //            num += metadata.TileSize;
        //        }
        //        if (num == 0L)
        //        {
        //            RebuildLevelMetadatas(task);
        //            AddMetadataItemToDB(task.dbPath, "LevelTilesMetadatas", Base64Util.ConvertObjToString(task.LevelTilesMetadatas));
        //        }
        //    }
        //}

        internal static bool RemoveAllMetaDataItem(string dbFile)
        {
            return SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbFile), "DELETE FROM metadata", null, null);
        }

        //internal static bool RemoveDownloadTask(DownloadTask task, bool deleteFile = false)
        //{
        //    if (deleteFile)
        //    {
        //        bool flag2;
        //        try
        //        {
        //            lock (removeDownloadTaskLock)
        //            {
        //                if (taskConns.ContainsKey(task.dbPath))
        //                {
        //                    taskConns[task.dbPath].Close();
        //                    taskConns[task.dbPath].Dispose();
        //                    taskConns.Remove(task.dbPath);
        //                }
        //                SQLiteConnection.ClearAllPools();
        //            }
        //            FileInfo info = new FileInfo(task.dbPath);
        //            if (info.Exists)
        //            {
        //                info.Delete();
        //            }
        //            goto Label_00AF;
        //        }
        //        catch (Exception exception)
        //        {
        //            LogUtil.Warn(string.Format("无法删除文件：{0}", task.Name), exception);
        //            flag2 = false;
        //        }
        //        return flag2;
        //    }
        //    Label_00AF:
        //    return RemoveTaskFromDB(task.ID);
        //}

        //internal static bool RemoveMetaDataItem(object proName, DownloadTask task)
        //{
        //    return SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(task.dbPath), "DELETE FROM metadata WHERE Name=@Name", new SQLiteParameter[] { new SQLiteParameter("@Name", proName) }, null);
        //}

        //private static bool RemoveTaskFromDB(object taskId)
        //{
        //    SQLiteParameter[] parameters = new SQLiteParameter[] { new SQLiteParameter("@ID", taskId) };
        //    return SQLiteHelper.ExcuteNoneQuery(GetTaskIndexDBConn, "DELETE FROM Tasks WHERE ID= @ID", parameters, null);
        //}

        internal static bool smethod_0(string dbPath, long length, int z)
        {
            SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), string.Format("UPDATE map SET tile_row=tile_row+1000000 WHERE zoom_level={0}", z), null, null);
            SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), string.Format("UPDATE map SET tile_row={0}-tile_row WHERE zoom_level={1}", length, z), null, null);
            return SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), string.Format("UPDATE map SET tile_row=tile_row+1000000 WHERE zoom_level={0}", z), null, null);
        }

        //internal static bool TileExist(string dbPath, DownloadTile tile)
        //{
        //    object obj2 = SQLiteHelper.ExecuteScalar(GetAZDBFileConn(dbPath), "select exists(select Zoom,X,Y from Tiles where Zoom=@Zoom and Y=@Y and X=@X)", new SQLiteParameter[] { new SQLiteParameter("@Z", tile.Z), new SQLiteParameter("@Y", tile.Y), new SQLiteParameter("@X", tile.X) });
        //    if (obj2 == null)
        //    {
        //        return false;
        //    }
        //    return bool.Parse(obj2.ToString());
        //}

        //internal static void UpdateTaskDynamicInfoToDB(DownloadTask task, SQLiteTransaction transAction = null)
        //{
        //    SQLiteConnection aZDBFileConn = GetAZDBFileConn(task.dbPath);
        //    if (aZDBFileConn == null)
        //    {
        //        aZDBFileConn = GetAZDBFileConn(task.dbPath);
        //    }
        //    SQLiteParameter[] parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "CurrentZ"), new SQLiteParameter("@Value", task.QueryZ) };
        //    SQLiteHelper.ExcuteNoneQuery(aZDBFileConn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, transAction);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "CurrentBundleIndex"), new SQLiteParameter("@Value", task.WritedBundleIndex) };
        //    SQLiteHelper.ExcuteNoneQuery(aZDBFileConn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, transAction);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "CurrentTileIndex"), new SQLiteParameter("@Value", task.WritedBundleTileIndex) };
        //    SQLiteHelper.ExcuteNoneQuery(aZDBFileConn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, transAction);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "SuccessCount"), new SQLiteParameter("@Value", task.SuccessCount) };
        //    SQLiteHelper.ExcuteNoneQuery(aZDBFileConn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, transAction);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "FailedCount"), new SQLiteParameter("@Value", task.FailedCount) };
        //    SQLiteHelper.ExcuteNoneQuery(aZDBFileConn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, transAction);
        //}

        //internal static void UpdateTaskStatusToDB(DownloadTask task)
        //{
        //    if ((task != null) && !string.IsNullOrEmpty(task.dbPath))
        //    {
        //        SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(task.dbPath), "UPDATE metadata set Value=@Status WHERE Name ='Status'", new SQLiteParameter[] { new SQLiteParameter("@Status", task.DisplayStatus) }, null);
        //    }
        //}

        //internal static void UpdateTaskSucFailInfoToDB(DownloadTask task, SQLiteTransaction transAction = null)
        //{
        //    SQLiteConnection aZDBFileConn = GetAZDBFileConn(task.dbPath);
        //    if (aZDBFileConn == null)
        //    {
        //        aZDBFileConn = GetAZDBFileConn(task.dbPath);
        //    }
        //    SQLiteParameter[] parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "SuccessCount"), new SQLiteParameter("@Value", task.SuccessCount) };
        //    SQLiteHelper.ExcuteNoneQuery(aZDBFileConn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, transAction);
        //    parameters = new SQLiteParameter[] { new SQLiteParameter("@Name", "FailedCount"), new SQLiteParameter("@Value", task.FailedCount) };
        //    SQLiteHelper.ExcuteNoneQuery(aZDBFileConn, "INSERT or REPLACE Into metadata(Name,Value) Values(@Name,@Value)", parameters, transAction);
        //}

        //internal static void UpdateTaskThreadsToDB(DownloadTask task)
        //{
        //    if ((task != null) && !string.IsNullOrEmpty(task.dbPath))
        //    {
        //        SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(task.dbPath), "UPDATE metadata set Value=@ThreadCount WHERE Name ='ThreadCount'", new SQLiteParameter[] { new SQLiteParameter("@ThreadCount", task.ThreadCount) }, null);
        //    }
        //}

        internal static bool Vacuum(string dbPath)
        {
            return SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(dbPath), "VACUUM;", null, null);
        }

        //internal static void WriteBundleToDB(DownloadTask task, int zoom, long bundleIndex, object bundle)
        //{
        //    SQLiteHelper.ExcuteNoneQuery(GetAZDBFileConn(task.dbPath), "INSERT or Replace into Bundles(Zoom,BundleIndex,Bundle) values(@Zoom,@BundleIndex,@Bundle)", new SQLiteParameter[] { new SQLiteParameter("@Zoom", zoom), new SQLiteParameter("@BundleIndex", bundleIndex), new SQLiteParameter("@Bundle", Base64Util.ConvertObjToByteArray(bundle)) }, null);
        //}

        //internal static void WriteFailedTilesToDB(string dbPath, Queue<DownloadTile> failedTiles)
        //{
        //    SQLiteConnection aZDBFileConn = GetAZDBFileConn(dbPath);
        //    lock (aZDBFileConn)
        //    {
        //        using (SQLiteCommand command = new SQLiteCommand(aZDBFileConn))
        //        {
        //            command.Transaction = aZDBFileConn.BeginTransaction();
        //            while (failedTiles.Count > 0)
        //            {
        //                DownloadTile tile = failedTiles.Dequeue();
        //                command.CommandText = "INSERT or REPLACE INTO Failures(Zoom,X,Y) values(@Zoom,@X,@Y)";
        //                SQLiteParameter[] parameters = new SQLiteParameter[] { new SQLiteParameter("@Zoom", tile.Z), new SQLiteParameter("@X", tile.X), new SQLiteParameter("@Y", tile.Y) };
        //                command.Parameters.Clear();
        //                SQLiteHelper.SetParameters(command.Parameters, parameters);
        //                command.ExecuteNonQuery();
        //            }
        //            command.Transaction.Commit();
        //        }
        //    }
        //}

        //private static SQLiteConnection GetTaskIndexDBConn
        //{
        //    get
        //    {
        //        if (taskIndexDBPathConn == null)
        //        {
        //            taskIndexDBPathConn = new SQLiteConnection();
        //            taskIndexDBPathConn.ConnectionString = TASK_INDEX_DB_CONN_STRING;
        //            try
        //            {
        //                if (!Directory.Exists("Download"))
        //                {
        //                    Directory.CreateDirectory("Download");
        //                }
        //                taskIndexDBPathConn.SetPassword(DATABASE_PW);
        //                taskIndexDBPathConn.Open();
        //                if (!SQLiteHelper.ContainTable(taskIndexDBPathConn, "Tasks"))
        //                {
        //                    SQLiteHelper.ExcuteNoneQuery(taskIndexDBPathConn, "CREATE Table Tasks(ID char(32) primary key,TaskDBPath TEXT not null);", null, null);
        //                }
        //            }
        //            catch (Exception exception)
        //            {
        //                LogUtil.Error("得到下载任务的数据库连接失败 " + TASK_INDEX_DB_CONN_STRING, exception);
        //            }
        //        }
        //        return taskIndexDBPathConn;
        //    }
        //}
    }
}
